#include "bluetoothconnect.h"
#include "ui_bluetoothconnect.h"



BluetoothConnect::BluetoothConnect(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::BluetoothConnect)
{
    ui->setupUi(this);

    m_service = nullptr;

    //设置设备列表的标题
    QListWidgetItem *item = new QListWidgetItem();
    //创建自定义的窗口 然后放入到listwidget中
    BtDevCell *bdc = new BtDevCell();
    //设置item的高
    item->setSizeHint(QSize(ui->lwShow->width(),bdc->height()));
    //设置label的显示
    bdc->btName->setText("名称");
    bdc->btAddr->setText("地址");
    bdc->btRssi->setText("信号强度");

    //把item加入到listwidget
    ui->lwShow->addItem(item);
    //设置item的窗口为自定义的窗口
    ui->lwShow->setItemWidget(item,bdc);

    //设置服务列表的标题
    QListWidgetItem *items = new QListWidgetItem();
    //创建自定义的窗口 然后放入到listwidget中
    BtDevCell *bdcs = new BtDevCell();
    //把item加入到listwidget
    items->setSizeHint(QSize(ui->lwService->width(),bdcs->height()));
    //设置label的显示
    bdcs->btName->setText("空");
    bdcs->btAddr->setText("服务Uuid");
    bdcs->btRssi->setText("空");
    //设置item的窗口为自定义的窗口
    ui->lwService->addItem(items);
    //设置item的窗口为自定义的窗口
    ui->lwService->setItemWidget(items,bdcs);

    //创建通信的socket 普通蓝牙使用
    //QBluetoothSocket *btSocket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol,this);


    //创建设备发现对象
    QBluetoothDeviceDiscoveryAgent *discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);
    QBluetoothLocalDevice *localDevice = new QBluetoothLocalDevice();

    discoveryAgent->setLowEnergyDiscoveryTimeout(20000);

    if( localDevice->hostMode() == QBluetoothLocalDevice::HostPoweredOff)//设备没有打开蓝牙
    {
        localDevice->powerOn();//调用打开本地的蓝牙设备
    }


    //点击搜索设备后开始搜索设备
    connect(ui->btnSerachDevice,&QPushButton::clicked,[=](){
        qDebug() << "开始搜索设备";
        //如果已经搜索过一次了，那么设计列表可能就大于1，那么就清空设备列表
        //但是标题也会被清除，所以重新构建
        if(ui->lwShow->count()>1)
        {
            ui->lwShow->clear();

            //设置设备列表的标题
            QListWidgetItem *item = new QListWidgetItem();
            //创建自定义的窗口 然后放入到listwidget中
            BtDevCell *bdc = new BtDevCell();
            //设置item的高
            item->setSizeHint(QSize(ui->lwShow->width(),bdc->height()));
            //设置label的显示
            bdc->btName->setText("名称");
            bdc->btAddr->setText("地址");
            bdc->btRssi->setText("信号强度");

            //把item加入到listwidget
            ui->lwShow->addItem(item);
            //设置item的窗口为自定义的窗口
            ui->lwShow->setItemWidget(item,bdc);
        }

        //开始搜索设备
        discoveryAgent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);


    });

    //搜索到设备后进入
    connect(discoveryAgent,&QBluetoothDeviceDiscoveryAgent::deviceDiscovered,[=](QBluetoothDeviceInfo devInfo){
        qDebug() << "搜索到设备";
        //名称不为空且是低功耗蓝牙
        if(devInfo.name() != "" && (devInfo.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration))
        {
            QListWidgetItem *item = new QListWidgetItem();
            BtDevCell *bdc = new BtDevCell();

            item->setSizeHint(QSize(ui->lwShow->width(),bdc->height()));

            bdc->btName->setText(devInfo.name());
            bdc->btAddr->setText(devInfo.address().toString());
            bdc->btRssi->setText(QString::number(devInfo.rssi()));

            ui->lwShow->addItem(item);
            ui->lwShow->setItemWidget(item,bdc);

            devInfos.append(devInfo);
        }
    });

    //搜索设备发生错误
    connect(discoveryAgent,&QBluetoothDeviceDiscoveryAgent::errorOccurred,[=](QBluetoothDeviceDiscoveryAgent::Error error){
        qDebug() << error;

        ui->teBTsearchInfo->append(QString::number(static_cast<int>(error))+"\n");
        //警告对话框
        QMessageBox::warning(this,"警告","搜索蓝牙设备发生错误，请检查蓝牙是否开启！");
    });

    //搜索设备完成
    connect(discoveryAgent,&QBluetoothDeviceDiscoveryAgent::finished,[=](){
        qDebug() << "搜索完成";
        ui->teBTsearchInfo->append("搜索完成\n");
    });

    //设备列表被点击事件
    connect(ui->lwShow,&QListWidget::itemClicked,[=](QListWidgetItem *item){
        //这是经典蓝牙的连接方式
        //        QWidget *widget = ui->lwShow->itemWidget(item);
        //        BtDevCell *wbdc = (BtDevCell *)widget;
        //        qDebug() << wbdc->btAddr->text().toUtf8().data();
        //        btSocket->connectToService(QBluetoothAddress(wbdc->btAddr->text().toUtf8().data()),QBluetoothUuid("00001101-0000-1000-8000-00805F9B34FB"),QIODevice::ReadWrite);
        qDebug() << "lwShow->count =" << ui->lwShow->count();
        if(ui->lwShow->count() <= 1)
            return;
        //这是低功耗蓝牙的连接方式
        qDebug() << "lwShow->currentRow =" << ui->lwShow->currentRow();
        //创建蓝牙控制器
        QLowEnergyController *lowBtControl = QLowEnergyController::createCentral(this->devInfos.at(ui->lwShow->currentRow()-1));
        //连接设备
        lowBtControl->connectToDevice();

        //连接成功后进入
        connect(lowBtControl,&QLowEnergyController::connected,[=](){
            qDebug() << "连接成功";
            //搜索服务
            lowBtControl->discoverServices();
            ui->teBTsearchInfo->append("连接成功\n");

        });

        //连接失败后进入
        connect(lowBtControl,&QLowEnergyController::errorOccurred,[=](QLowEnergyController::Error newError){
            qDebug() << newError;
            ui->teBTsearchInfo->append(QString::number(static_cast<int>(newError))+"连接失败\n");
        });

        //搜索到服务后进入
        connect(lowBtControl,&QLowEnergyController::serviceDiscovered, [=](QBluetoothUuid serviceUuid) {
            qDebug() << "发现服务";

            QListWidgetItem *item = new QListWidgetItem();
            BtDevCell *bdc = new BtDevCell();

            item->setSizeHint(QSize(ui->lwService->width(),bdc->height()));

            bdc->btName->setText("");
            bdc->btAddr->setText(serviceUuid.toString());
            bdc->btRssi->setText("");

            ui->lwService->addItem(item);
            ui->lwService->setItemWidget(item,bdc);

            btUuids.append(serviceUuid);
        });

        //服务uuid列表被点击事件
        connect(ui->lwService,&QListWidget::itemClicked,[=](){

            if (ui->lwService->currentRow() <= 1)
                return;

            QBluetoothUuid serviceUuid = btUuids.at(ui->lwService->currentRow()-1);
            //创建服务
            this->m_service = lowBtControl->createServiceObject(QBluetoothUuid(serviceUuid),this);
            if(m_service==NULL)
            {
                qDebug() << "服务建立失败!";
                ui->teBTsearchInfo->append("服务建立失败\n");
            }
            else
            {
                qDebug() << "服务建立成功!";
                ui->teBTsearchInfo->append("服务建立成功\n");

                // 服务对象创建成功后，坚听服务状态变化，如果状态变成已发现，则进行后续服务下特征对象获取
                connect(m_service,&QLowEnergyService::stateChanged, this, [this]() {
                    //qDebug() << "service state change" << m_service->state();
                    //发现服务, 建立characteristic对象实例
                    if(m_service->state() == QLowEnergyService::ServiceDiscovered) {

                        //获取特征对象
                        QList<QLowEnergyCharacteristic> list=m_service->characteristics();

                        int writeNoResp_characteristic = -1;
                        for(int i=0;i<list.count();i++)
                        {
                            this->m_characteristic = list.at(i);


                            //qDebug() << c.properties();
                            /*如果QLowEnergyCharacteristic对象有效，则返回true，否则返回false*/
                            if(m_characteristic.isValid())
                            {
                                if ((m_characteristic.properties() & QLowEnergyCharacteristic::WriteNoResponse)
                                    && (m_characteristic.properties() & QLowEnergyCharacteristic::Write))
                                {
                                    writeNoResp_characteristic = i;
                                }
                                ui->teBTsearchInfo->append(m_characteristic.uuid().toString()+" properties="+QString::number(static_cast<int>(m_characteristic.properties()))+"\n");
                                //描述符定义特征如何由特定客户端配置。
                                QLowEnergyDescriptor m_notificationDesc = m_characteristic.descriptor(QBluetoothUuid::DescriptorType::ClientCharacteristicConfiguration);
                                if(m_notificationDesc.isValid())
                                {
                                    //写描述符
                                    m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("0100"));
                                    //m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("FEE1"));
                                }
                                //ui->teBTsearchInfo->append("m_notificationDesc.name="+m_notificationDesc.name());
                            }
                        }

                        if (writeNoResp_characteristic >= 0)
                        {
                            this->m_characteristic = list.at(writeNoResp_characteristic);
                            ui->teBTsearchInfo->append("writeNoResp_characteristic OK\n");
                        }
                    }
                });

                //通知主窗口可以连接service了
                emit toConectCharacteristic(m_service);

                // 触发服务详情发现函数 ，不要忘记调用
                m_service->discoverDetails();
            }
        });
    });

    //    //普通蓝牙使用
    //    connect(btSocket,&QBluetoothSocket::connected,[=](){
    //        qDebug() << "连接完成";
    //    });

    //    connect(btSocket,&QBluetoothSocket::errorOccurred,[=](QBluetoothSocket::SocketError error){
    //        qDebug() << "连接失败:" <<error;
    //    });

}


BluetoothConnect::~BluetoothConnect()
{
    delete ui;
}
